const fs = require("fs")
const path = require("path")

const struct = JSON.parse(fs.readFileSync(path.resolve("struct.json")))
const baseFolder = path.resolve()

function formatTable(text) {
    let rows = [];
    let rowsNoIndentPattern = new RegExp(/^\s*(\S.*)$/gum);
    let match = null;
    while ((match = rowsNoIndentPattern.exec(text)) !== null) {
        rows.push(match[1].trim());
    }
    // Desired width of each column
    let colWidth = [];
    // Regex to extract cell content.
    // Known issue: `\\|` is not correctly parsed as a valid delimiter
    let fieldRegExp = new RegExp(/(?:\|?((?:\\\||`.*?`|[^\|])+))/gu)
    let cjkRegex = /[\u3000-\u9fff\uff01-\uff60‘“’”—]/g
    let lines = rows.map((row, num) => {
        let field = null
        let values = []
        let i = 0;
        while ((field = fieldRegExp.exec(row)) !== null) {
            let cell = field[1].trim()
            values.push(cell)
            // Ignore length of dash-line to enable width reduction
            if (num != 1) {
                // Treat CJK characters as 2 English ones because of Unicode stuff
                let length = cjkRegex.test(cell) ? cell.length + cell.match(cjkRegex).length : cell.length
                colWidth[i] = colWidth[i] > length ? colWidth[i] : length
            }
            i++
        }
        return values
    })
    // Normalize the num of hyphen, use Math.max to determine minimum length based on dash-line format
    lines[1] = lines[1].map((cell, i) => {
        if (/:-+:/.test(cell)) {
            //:---:
            colWidth[i] = Math.max(colWidth[i], 5);
            return ':' + '-'.repeat(colWidth[i] - 2) + ':'
        } else if (/:-+/.test(cell)) {
            //:---
            colWidth[i] = Math.max(colWidth[i], 4)
            return ':' + '-'.repeat(colWidth[i] - 1)
        } else if (/-+:/.test(cell)) {
            //---:
            colWidth[i] = Math.max(colWidth[i], 4)
            return '-'.repeat(colWidth[i] - 1) + ':'
        } else if (/-+/.test(cell)) {
            //---
            colWidth[i] = Math.max(colWidth[i], 3);
            return '-'.repeat(colWidth[i])
        }
    })
    return lines.map(row => {
        let cells = row.map((cell, i) => {
            let cellLength = colWidth[i]
            if (cjkRegex.test(cell)) {
                cellLength -= cell.match(cjkRegex).length
            }
            return (cell + ' '.repeat(cellLength)).slice(0, cellLength)
        });
        return '| ' + cells.join(' | ') + ' |'
    }).join('\r\n')
}

let generatedContent = `# 接口列表\r\n`
for (let section in struct) {
    generatedContent += `\r\n## ${struct[section]}\r\n\r\n`
    let table =
        `| name | method | url | document |\r\n` +
        `| :--- | :----: | :-- | :------: |\r\n`

    const sectionFolder = `${baseFolder}/${section}`
    const children = fs.readdirSync(sectionFolder)
    const rows = []
    for (let child of children) {
        const childPath = sectionFolder + "/" + child
        const lines = fs.readFileSync(childPath, { encoding: "utf8" }).split('\r\n')
        const name = lines[0].substring(2).trim()
        const link = `[document](${section}/${child})`

        for (const line of lines) {
            if (!line.match(/^`(POST)|(GET)|(DELETE)|(PUT)|(PATCH)`.*/i)) continue
            const [method, url] = line.trim().split(" ")
            rows.push({ name, link, method, url })
            break
        }
    }

    for (let row of rows) {
        table += `| ${row.name} | ${row.method} | ${row.url} | ${row.link} |\r\n`
    }
    generatedContent += formatTable(table)
    generatedContent += "\r\n"
}
fs.writeFileSync(`${baseFolder}/README.md`, generatedContent)
